<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="google-site-verification" content="VGgQeH6NiuAKspyCFT7dqUNmNhg6RJoMYQXErdy0jgE" />
  <meta name="baidu-site-verification" content="code-yNmdsKJ9GP" />
  
  
  <meta name="keywords" content="Elasticsearch,elasticsearch,搭建，环境搭建,">
  
  
  <meta name="description" content="Elasticsearch 环境搭建">
  
  <title>
    14. Elasticsearch 聚合性能优化 |
    
    思远程序
  </title>
  <!-- Icon -->
  
    <link rel="shortcut icon" href="/favicon.ico">
    
  
<link rel="stylesheet" href="/css/style.css">

  
  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">

  
  
<script src="/js/pace.min.js"></script>

<meta name="generator" content="Hexo 6.2.0"></head>

<body>
  <main class="content">
    <section class="outer">
  <article id="post-14. Elasticsearch 聚合性能优化" class="article article-type-post" itemscope
  itemprop="blogPost" data-scroll-reveal>

  <div class="article-inner">
    
    <header class="article-header">
      

<h1 class="article-title" itemprop="name">
  14. Elasticsearch 聚合性能优化
</h1>



    </header>
    

    
    <div class="article-meta">
      <a href="/2022/07/23/14.%20Elasticsearch%20%E8%81%9A%E5%90%88%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" class="article-date">
  <time datetime="2022-07-23T15:00:00.000Z" itemprop="datePublished">2022-07-23</time>
</a>
      
<div class="article-category">
  <a class="article-category-link" href="/categories/%E5%88%86%E5%B8%83%E5%BC%8F%E6%A1%86%E6%9E%B6/">分布式框架</a>
</div>

    </div>
    

    
    
<div class="tocbot"></div>

    

    <div class="article-entry" itemprop="articleBody">
      
      
      
      <h5 id="启用-eager-global-ordinals-提升高基数聚合性能"><a href="#启用-eager-global-ordinals-提升高基数聚合性能" class="headerlink" title="启用 eager global ordinals 提升高基数聚合性能"></a>启用 eager global ordinals 提升高基数聚合性能</h5><p>适用场景：高基数聚合 。<br>高基数聚合场景中的高基数含义：一个字段包含很大比例的唯一值。<br>global ordinals 中文翻译成全局序号，是一种数据结构，应用场景如下： </p>
<ul>
<li>基于 keyword，ip 等字段的分桶聚合，包含：terms聚合、composite 聚合 等。 </li>
<li>基于text 字段的分桶聚合（前提条件是：fielddata 开启）。 </li>
<li>基于父子文档 Join 类型的 has_child 查询和 父聚合。</li>
</ul>
<span id="more"></span>

<p>global ordinals 使用一个数值代表字段中的字符串值，然后为每一个数值分配一个 bucket（分桶）。<br>global ordinals 的本质是：启用 eager_global_ordinals 时，会在刷新（refresh）分片时 构建全局序号。这将构建全局序号的成本从搜索阶段转移到了数据索引化（写入）阶段。<br>创建索引的同时开启：eager_global_ordinals。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">PUT /my‐index</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;tags&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;eager_global_ordinals&quot;</span><span class="punctuation">:</span> <span class="keyword">true</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<p>注意：开启 eager_global_ordinals 会影响写入性能，因为每次刷新时都会创建新的全局序 号。为了最大程度地减少由于频繁刷新建立全局序号而导致的额外开销，请调大刷新间隔 refresh_interval。<br>动态调整刷新频率的方法如下：</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">PUT /my_index/_settings</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;refresh_interval&quot;</span><span class="punctuation">:</span> <span class="string">&quot;30s&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<p>该招数的本质是：以空间换时间。</p>
<h5 id="插入数据时对索引进行预排序"><a href="#插入数据时对索引进行预排序" class="headerlink" title="插入数据时对索引进行预排序"></a>插入数据时对索引进行预排序</h5><ul>
<li>Index sorting （索引排序）可用于在插入时对索引进行预排序，而不是在查询时再对索引进行排序，这将提高范围查询（range query）和排序操作的性能。 </li>
<li>在 Elasticsearch 中创建新索引时，可以配置如何对每个分片内的段进行排序。 </li>
<li>这是 Elasticsearch 6.X 之后版本才有的特性。<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">PUT /my‐index</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;sort.field&quot;</span><span class="punctuation">:</span> <span class="string">&quot;create_time&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;sort.order&quot;</span><span class="punctuation">:</span> <span class="string">&quot;desc&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;create_time&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;date&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
注意：预排序将增加 Elasticsearch 写入的成本。<br>在某些用户特定场景下，开启索引预排序 会导致大约 40%-50% 的写性能下降。也就是说，如果用户场景更关注写性能的业务，开 启索引预排序不是一个很好的选择。</li>
</ul>
<h5 id="使用节点查询缓存"><a href="#使用节点查询缓存" class="headerlink" title="使用节点查询缓存"></a>使用节点查询缓存</h5><p>节点查询缓存（Node query cache）可用于有效缓存过滤器（filter）操作的结果。如果多 次执行同一 filter 操作，这将很有效，但是即便更改过滤器中的某一个值，也将意味着需要 计算新的过滤器结果。<br>例如，由于 “now” 值一直在变化，因此无法缓存在过滤器上下文中使用 “now” 的查 询。<br>那怎么使用缓存呢？通过在 now 字段上应用 datemath 格式将其四舍五入到最接近的分 钟&#x2F;小时等，可以使此类请求更具可缓存性，以便可以对筛选结果进行缓存。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">PUT /my_index/_doc/<span class="number">1</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;create_time&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2022‐07‐27T16:00:55.328Z&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"></span><br><span class="line"> #下面的示例无法使用缓存</span><br><span class="line">GET /my_index/_search</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;constant_score&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;filter&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;range&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;create_time&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;gte&quot;</span><span class="punctuation">:</span> <span class="string">&quot;now‐1h&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;lte&quot;</span><span class="punctuation">:</span> <span class="string">&quot;now&quot;</span></span><br><span class="line">          <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"></span><br><span class="line"> # 下面的示例就可以使用节点查询缓存。</span><br><span class="line">GET /my_index/_search</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;constant_score&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;filter&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;range&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;create_time&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;gte&quot;</span><span class="punctuation">:</span> <span class="string">&quot;now‐1h/m&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;lte&quot;</span><span class="punctuation">:</span> <span class="string">&quot;now/m&quot;</span></span><br><span class="line">          <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>
<p>上述示例中的“now-1h&#x2F;m” 就是 datemath 的格式。<br>如果当前时间 now 是：16:31:29，那么range query 将匹配 my_date 介于：15:31:00 和 15:31:59 之间的时间数据。同理，聚合的前半部分 query 中如果有基于时间查询，或者后 半部分 aggs 部分中有基于时间聚合的，建议都使用 datemath 方式做缓存处理以优化性 能。</p>
<h5 id="使用分片请求缓存"><a href="#使用分片请求缓存" class="headerlink" title="使用分片请求缓存"></a>使用分片请求缓存</h5><p>聚合语句中，设置：size：0，就会使用分片请求缓存缓存结果。size &#x3D; 0 的含义是：只返 回聚合结果，不返回查询结果。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">GET /es_db/_search</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;size&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;aggs&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;remark_agg&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;terms&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;field&quot;</span><span class="punctuation">:</span> <span class="string">&quot;remark.keyword&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"> </span><br></pre></td></tr></table></figure>
<h5 id="拆分聚合，使聚合并行化"><a href="#拆分聚合，使聚合并行化" class="headerlink" title="拆分聚合，使聚合并行化"></a>拆分聚合，使聚合并行化</h5><p>Elasticsearch 查询条件中同时有多个条件聚合，默认情况下聚合不是并行运行的。当为每 个聚合提供自己的查询并执行 msearch 时，性能会有显著提升。因此，在 CPU 资源不是 瓶颈的前提下，如果想缩短响应时间，可以将多个聚合拆分为多个查询，借助：msearch 实现并行聚合。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"> #常规的多条件聚合实现</span><br><span class="line">GET /employees/_search</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;size&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;aggs&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;jobs_agg&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;terms&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;field&quot;</span><span class="punctuation">:</span> <span class="string">&quot;job.keyword&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;max_salary&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;max&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;field&quot;</span><span class="punctuation">:</span> <span class="string">&quot;salary&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"> </span><br><span class="line"># _msearch 拆分多个语句的聚合实现</span><br><span class="line">GET /_msearch</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="string">&quot;employees&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;size&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;aggs&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;jobs_agg&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;terms&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;field&quot;</span><span class="punctuation">:</span> <span class="string">&quot;job.keyword&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="string">&quot;employees&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;size&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;aggs&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;max_salary&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;max&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;field&quot;</span><span class="punctuation">:</span> <span class="string">&quot;salary&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"> </span><br></pre></td></tr></table></figure>






















      
    </div>
    <footer class="article-footer">
      <a data-url="https://siyit.gitee.io/2022/07/23/14.%20Elasticsearch%20%E8%81%9A%E5%90%88%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" data-id="cl6bukbt3000fsu6fehln0kz8" class="article-share-link">
        分享
      </a>
      
<ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Elasticsearch/" rel="tag">Elasticsearch</a></li></ul>

    </footer>

  </div>

  
  
<nav class="article-nav">
  
  <a href="/2022/10/25/mybatis-plus-%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90/" class="article-nav-link">
    <strong class="article-nav-caption">前一篇</strong>
    <div class="article-nav-title">
      
      mybatis-plus 多数据源
      
    </div>
  </a>
  
  
  <a href="/2022/07/23/13.%20Elasticsearch%20%E8%81%9A%E5%90%88%E5%88%86%E6%9E%90%E4%B8%8D%E7%B2%BE%E5%87%86%E5%8E%9F%E5%9B%A0/" class="article-nav-link">
    <strong class="article-nav-caption">后一篇</strong>
    <div class="article-nav-title">13. Elasticsearch 聚合分析不精准原因</div>
  </a>
  
</nav>

  

  
  
<div class="vcomments" id="vcomments"></div>

<script src="https://unpkg.com/valine/dist/Valine.min.js"></script>

<script>
  new Valine({
    el: '#vcomments',
    appId: 'A7Ny5JW4l2XoShLWoQfpND2b-gzGzoHsz',
    appKey: 'lTbAjSoXEDQETkbAcE4zpYpu',
    notify: 'true',
    verify: 'true',
    avatar: 'identicon',
    pageSize: '10',
    placeholder: '请输入...'
  })
</script>

  
  

</article>
</section>
    <footer class="footer">
  <div class="outer">
    <div class="float-right">
      <ul class="list-inline">
  
  <li><i class="fe fe-smile-alt"></i> <span id="busuanzi_value_site_uv"></span></li>
  
  <li><i class="fe fe-bookmark"></i> <span id="busuanzi_value_page_pv"></span></li>
  
</ul>
    </div>
    <ul class="list-inline">
      <li>思远程序 &copy; 2022</li>
      
        <li></li>
      
      <li>Powered by <a href="http://hexo.io/" target="_blank">Hexo</a></li>
      <li>theme  <a target="_blank" rel="noopener" href="https://github.com/zhwangart/hexo-theme-ocean">Ocean</a></li>
    </ul>
  </div>
</footer>
  </main>
  <aside class="sidebar">
    <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/hexo.svg" alt="思远程序"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/recommend">推荐</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/gallery">相册</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/favorites">收藏</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/about">关于</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link nav-item-search" title="搜索">
        <i class="fe fe-search"></i>
        搜索
      </a>
    </li>
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      <div class="totop" id="totop">
  <i class="fe fe-rocket"></i>
</div>
    </li>
    <li class="nav-item">
      
      <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
        <i class="fe fe-feed"></i>
      </a>
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
  </aside>
  
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/jquery.justifiedGallery.min.js"></script>


<script src="/js/lazyload.min.js"></script>


<script src="/js/busuanzi-2.3.pure.min.js"></script>



<script src="/fancybox/jquery.fancybox.min.js"></script>





<script src="/js/tocbot.min.js"></script>


<script>
  // Tocbot_v4.7.0  http://tscanlin.github.io/tocbot/
  tocbot.init({
    tocSelector: '.tocbot',
    contentSelector: '.article-entry',
    headingSelector: 'h1, h2, h3, h4, h5, h6',
    hasInnerContainers: true,
    scrollSmooth: true,
    positionFixedSelector: '.tocbot',
    positionFixedClass: 'is-position-fixed',
    fixedSidebarOffset: 'auto',
  });
</script>



<script src="/js/ocean.js"></script>

</body>

</html>